/**********************************************
This file demonstrates module system and macro
and complex data structures.
**********************************************/

mod mods; // 表示引用mod模块
use mods::test::test1::test2::p2; // 类似于C#的命名空间
use std::collections::LinkedList;
use std::collections::VecDeque;
use std::io::stdin;

const CONSTANT: &str = "const";

fn main() {
    //---------------string--------------------
    let str1: &str = "Hello world!";
    let str2: String = String::from("Hello world!");
    println!("{0}\n{1}", str1, str2);
    println!("{}", CONSTANT);
    //----------------vector-------------------
    let mut vector: Vec<u8> = vec![1, 2, 3, 4, 5, 6, 7];
    vector.push(23);
    vector.push(54);
    println!("{:?}", vector);
    let mut buffer: VecDeque<i32> = VecDeque::new();
    buffer.push_front(1);
    buffer.push_front(23);
    println!("{:?}", buffer);
    // let mut buf = VecDeque::new();
    // stdin().read_line(buf);
    //-----------Double Ended Queue------------
    let mut VDQ = VecDeque::new();
    VDQ.push_front("Hello ");
    VDQ.push_back("world!");
    println!("{0}{1}", VDQ[0], VDQ[1]);
    //--------------linked list----------------
    let mut linkedlist = LinkedList::new();
    linkedlist.push_front("Hel");
    linkedlist.push_back("lo");
    linkedlist.push_back(" world!");
    for character in linkedlist {
        print!("{}", character);
    }
    println!();
    // println!("{}", linkedlist);
    //---------------mod test------------------
    let text = String::from("text");
    mods::test::p(text);
    p2(43);
    mods::test::test1::p1(432);
    //-------------smart pointer---------------
    #[derive(PartialEq, Debug)]
    struct Pixel {
        r: u16,
        g: u16,
        b: u16
    }
    let pixel = Box::new(Pixel { r: 255, g: 255, b: 255 });
    let pix = *pixel;
    assert_eq!(pix, Pixel { r: 255, g: 255, b: 255 });
    println!("{:#?}", pix);
    //-----------------Generic-----------------
    let strs: Option<&str> = Some("hello");
    match strs {
        Some(str) => println!("{:?}", str),
        None => println!("None")
    }
    //------------------trait------------------
    struct Duck;
    struct Pig;
    trait Fly {
        fn fly(&self) -> bool;
    }
    impl Fly for Duck {
        fn fly(&self) -> bool {
            return true;
        }
    }
    impl Fly for Pig {
        fn fly(&self) -> bool {
            return false;
        }
    }
    fn fly_static<T: Fly>(uses: T) -> bool {
        uses.fly()
    }
    let pig = Pig;
    let duck = Duck;
    assert_eq!(fly_static::<Pig>(pig), false);
    assert_eq!(fly_static::<Duck>(duck), true);
}
